package au.com.georgi.wave;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Logger;

import org.w3c.dom.Document;

import au.com.georgi.wave.entity.ArmoryCharacter;
import au.com.georgi.wave.matcher.PatternMatcher;
import au.com.georgi.wave.parser.ArmoryParser;
import au.com.georgi.wave.parser.PortraitParser;
import au.com.georgi.wave.reader.HTMLWebsiteReader;
import au.com.georgi.wave.reader.XMLWebsiteReader;

import com.google.wave.api.AbstractRobotServlet;
import com.google.wave.api.Blip;
import com.google.wave.api.Event;
import com.google.wave.api.Gadget;
import com.google.wave.api.Range;
import com.google.wave.api.RobotMessageBundle;
import com.google.wave.api.TextView;
import com.google.wave.api.Wavelet;

public class WarcraftyServlet extends AbstractRobotServlet {

	private static final Logger log = Logger.getLogger(WarcraftyServlet.class
			.getName());
	private static final String APP_BOT_NAME = "war-crafty@appspot.com";
	// [optional http][optional www][optional two letter prefix eg.eu.]
	// [wowarmory or armory][optional word eg.
	// wow-armory.][com/character-sheet.xml?r=][word &n= word]
	public static final String PATTERN = "(http://)?(www.)?([a-zA-Z]{2}\\.)?(wow)?armory.(.+\\.)?com/character-sheet.xml\\?r=(.+\\&)(n=\\w+)(/)?";
	private static final String GADGET_XML = "http://warcrafty.googlecode.com/svn/trunk/warcrafty/gadget/armoryGadget.xml";

	@Override
	public void processEvents(RobotMessageBundle bundle) {
		Wavelet wavelet = bundle.getWavelet();

		for (Event event : bundle.getEvents()) {
			switch (event.getType()) {
			case WAVELET_SELF_ADDED:
				getWelcomeText(wavelet);
				break;
			case BLIP_SUBMITTED:
				if (!(event.getModifiedBy().equalsIgnoreCase(APP_BOT_NAME))) {
					onBlipSubmitted(event.getBlip());
				}
				break;
			default:
				break;
			}
		}
	}

	private void onBlipSubmitted(Blip blip) {
		ArmoryCharacter character = new ArmoryCharacter();
		TextView document = blip.getDocument();
		String docText = document.getText();
		URL armoryURL = null;

		try {
			armoryURL = getURL(PatternMatcher.getURL(PATTERN, docText));
		} catch (MalformedURLException e) {
			log.severe("Couldn't connect to the Armory.");
		}

		if (armoryURL != null) {
			log.warning("Armory URL detected " + armoryURL.toString());

			character = parseHTML(armoryURL);

			Range rangeToReplace = PatternMatcher.getRange(PATTERN, docText);

			Gadget gadget = new Gadget(GADGET_XML);
			gadget.setField("charName", character.getName());
			gadget.setField("charClass", character.getCharClass());
			gadget.setField("faction", character.getFaction());
			gadget.setField("guildName", character.getGuildName());
			gadget.setField("race", character.getRace());
			gadget.setField("realm", character.getRealm());
			gadget.setField("portraitURL",
					parseHTMLForPortraitImageURL(armoryURL));
			gadget.setField("level", character.getLevel());
			gadget.setField("originalURL", armoryURL.toString());

			log.warning("Sent data to gadget..." + character.toString());

			document.delete(rangeToReplace);
			document.insertElement(rangeToReplace.getStart(), gadget);
		}

	}

	private ArmoryCharacter parseHTML(URL url) {
		Document website = XMLWebsiteReader.readWebsite(url);
		ArmoryParser parser = new ArmoryParser(website);
		return parser.parseSource();
	}

	private String parseHTMLForPortraitImageURL(URL url) {
		String rawWebsite = HTMLWebsiteReader.readWebsite(url);
		PortraitParser parser = new PortraitParser(rawWebsite);
		return parser.parseSource();
	}

	private URL getURL(String armoryURL) throws MalformedURLException {
		if (armoryURL == null)
			return null;
		if (armoryURL.startsWith("http://") || armoryURL.startsWith("www.")) {
			return new URL(armoryURL);

		}
		return new URL("http://" + armoryURL);
	}

	private void getWelcomeText(Wavelet wavelet) {
		Blip blip = wavelet.appendBlip();
		TextView textview = blip.getDocument();
		textview
				.append("Hi! I can display World Of Warcraft character stats, just add in the characters armory link.");
	}

}
